﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Meraz.Core.Model;
using System.Diagnostics;
using Meraz.Core.Factories;
using Meraz.Core.Repositories;
using Meraz.Core.Data;
using Ninject;
using Meraz.Core.Commands;

namespace Meraz.Core.Managers
{
    public class DomainManager
    {
        [Inject]
        public IDomainRepository DomainRepository { get; set; }
        [Inject]
        public IObjectFactory ObjectFactory { get; set; }

        public List<Domain> All()
        {
            return DomainRepository.All();
        }
        public List<Domain> GetTwitterDomains()
        {
            throw new NotImplementedException();
        }
        public List<Domain> Get(int pageSize, int pageIndex){
            List<Domain> list = new List<Domain>();
            try
            {
                list.AddRange(DomainRepository.Page(pageSize, pageIndex));
            }
            catch (ArgumentNullException)
            {
                //sink
            }
            return list;
        }

        public Domain GetFromLink(string link)
        {
            try
            {
                IEnumerable<string> domainNames = ExtractDomains(link).Reverse();
                bool checkFirst = true;
                string domainName = null;
                Domain parent = null;
                Domain result = null;
                for (int domainIndex = 0; domainIndex < domainNames.Count(); domainIndex++)
                {
                    domainName = domainNames.ElementAt(domainIndex);
                    if (checkFirst)
                    {
                        result = DomainRepository.Get(domainName);
                    }
                    if (result == null)
                    {
                        checkFirst = false;
                        result = new Domain();
                        DomainRepository.Add(result);
                        result.Name = domainName;
                        result.Parent = parent;
                    }
                    parent = result;
                }
                return result;
            }
            catch (Exception ex)
            {
                Debug.WriteLine(string.Format("Problem with link '{0}:'", link));
                Debug.WriteLine(ex);
                throw ex;
            }
        }

        public IEnumerable<string> ExtractDomains(string link)
        {
            Debug.WriteLine(string.Format("ExtractDomains from '{0}'", link));
            List<string> domains = new List<string>();
            string domain = null;
            Uri uri = new Uri(link);
            if (!uri.IsAbsoluteUri)
                return null;
            string fullDomain = uri.Host;
            if (fullDomain.StartsWith("www."))
                fullDomain = fullDomain.Substring(4);
            string[] tokens = fullDomain.Split('.');
            Debug.Assert(tokens.Length > 1);
            domain = fullDomain;
            domains.Add(domain);
            for (int i = 0; i < tokens.Length; i++)
            {
                int dotIndex = domain.IndexOf('.', i);
                if (dotIndex > -1)
                    domain = domain.Substring(dotIndex + 1);
                if (domain.Contains('.'))
                    domains.Add(domain);
            }
            return domains;
        }

        public void Save(IEnumerable<Domain> domains)
        {
            ISaveDomainsCommand command = ObjectFactory.GetSaveDomainsCommand(domains);
            command.Execute();
        }
    }
}
